package com.sykj.huxianlong.controller;


import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.sykj.bean.activiti.WorkFlowParam;
import com.sykj.huxianlong.entity.*;
import com.sykj.huxianlong.service.IFlowInfoService;
import com.sykj.huxianlong.service.ISystemService;
import com.sykj.huxianlong.service.IVacationOrderService;
import com.sykj.huxianlong.service.IWorkFlowRepositoryService;
import com.sykj.util.reponse.ResultBody;
import lombok.val;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
@CrossOrigin
@RequestMapping("flows")
public class HxlFlowController {


    @Autowired
    private ISystemService systemService;
    @Autowired
    private RepositoryService repositoryService;

    @Autowired    private IWorkFlowRepositoryService workFlowRepositoryService;
    @Autowired
    private IFlowInfoService flowInfoService;
    @Autowired
    private IVacationOrderService vacationOrderService;

    @GetMapping("/list")
    public List<WorkFlowParam> list(Integer page, Integer limit) {
        val processList = workFlowRepositoryService.getProcessList(page, limit);
        List<WorkFlowParam> workFlowParams = new ArrayList<>();
        for (ProcessDefinition processDefinition : processList) {
            val param = new WorkFlowParam();
            param.setId(processDefinition.getId());
            param.setName(processDefinition.getName());
            param.setDescription(processDefinition.getDescription());
            param.setKey(processDefinition.getKey());
            param.setVersion(processDefinition.getVersion());
            workFlowParams.add(param);
        }
        return workFlowParams;
    }


    /**
     * 请假列表查询
     *
     * @param
     * @return
     */
    @RequestMapping("queryList")
    @ResponseBody
    public List<VacationOrderVo> queryList() {
        List<VacationOrderVo> vacationOrderPage = vacationOrderService.queryVacationOrder();
        return vacationOrderPage;
    }

 // t统计
    @RequestMapping("querysta")
    @ResponseBody
    public List<VacationOrderVo> querysta( String userId){
        List<VacationOrderVo> statisticsList=vacationOrderService.querysta(userId);
        return  statisticsList;
    }

    @RequestMapping("querystaa")
    @ResponseBody
    public List<VacationOrderVo> querystaa(){
        List<VacationOrderVo> statisticsList=vacationOrderService.querystaa();
        return  statisticsList;
    }

    /**
     * 部署流程
     *
     * @param
     * @param
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "deployModel", method = RequestMethod.POST)
    @ResponseBody
    public ResultBody deployModel(String modelId) throws IOException {
//        String modelId = request.getParameter("modelId");
        if (StringUtils.isNoneBlank(modelId)) {
            Model modelData = this.repositoryService.getModel(modelId);
            ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
            byte[] bpmnBytes = null;

            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            bpmnBytes = new BpmnXMLConverter().convertToXML(model);
            String processName = modelData.getName() + ".bpmn20.xml";
            Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes, "utf-8")).deploy();
            modelData.setDeploymentId(deployment.getId());
            repositoryService.saveModel(modelData);
            //向流程定义表保存数据
            FlowDef flowDef = new FlowDef();
            List<Process> processes = model.getProcesses();
            for (Process process : processes) {
                flowDef.setFlowCode(process.getId());
                flowDef.setFlowName(process.getName());
            }
            flowInfoService.insertFlowDef(flowDef);

            return new ResultBody("10001", "部署成功");
        }
        return new ResultBody("10003", "系统异常,流程ID不存在。");
    }


    /**
     * 发布流程
     *
     * @param modelId 模型ID
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/publish", method = RequestMethod.POST)
    public ResultBody publish(String modelId) {
        ResultBody rb = new ResultBody();

        Map<String, String> map = new HashMap<String, String>();
        try {
            Model modelData = repositoryService.getModel(modelId);
            byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());
            if (bytes == null) {

                rb.setCode("10012");
                rb.setMessage("部署ID:{}的模型数据为空，请先设计流程并成功保存");
            }
            JsonNode modelNode = new ObjectMapper().readTree(bytes);
            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            Deployment deployment = repositoryService.createDeployment()
                    .name(modelData.getName())
                    .addBpmnModel(modelData.getKey() + ".bpmn20.xml", model)
                    .deploy();
            modelData.setDeploymentId(deployment.getId());
            repositoryService.saveModel(modelData);
            rb.setCode("10011");
            rb.setMessage("部署成功保存");

        } catch (Exception e) {

            rb.setCode("10013");
            rb.setMessage("部署modelId:{}模型服务异常：{}");

        }

        return rb;
    }

    /**
     * 发布模型为流程定义
     */
    @RequestMapping(value = "/deploy", method = RequestMethod.POST)
    public ResultBody deploy(String modelId) throws Exception {

        //获取模型
        Model modelData = repositoryService.getModel(modelId);
        //模板id
        byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());

        //repositoryService.getBpmnModel()

        if (bytes == null) {
            return new ResultBody("10003", "模型数据为空，请先设计流程并成功保存，再进行发布", null);
            //  "模型数据为空，请先设计流程并成功保存，再进行发布。";
        }

        JsonNode modelNode = new ObjectMapper().readTree(bytes);

        BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
        if (model.getProcesses().size() == 0) {
            return new ResultBody("-11", "数据模型不符要求，请至少设计一条主线流程", null);
            // return "数据模型不符要求，请至少设计一条主线流程。";
        }
        byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);
        //发布流程
        String processName = modelData.getName() + ".bpmn20.xml";
        Deployment deployment = repositoryService.createDeployment()
                .name(modelData.getName())
                .addString(processName, new String(bpmnBytes, "UTF-8"))
                .deploy();

        modelData.setDeploymentId(deployment.getId());
        repositoryService.saveModel(modelData);
        return new ResultBody("10011", "成功");
    }

    //提交请假单
    @PostMapping("saveOrder")
    @ResponseBody
    public ResultBody saveOrder(@RequestBody VacationOrder vacationOrder) {
        System.out.println(vacationOrder);
        try{
            vacationOrderService.insertVacationOrder(vacationOrder);
            return  new ResultBody("10021","添加成功");
        }
        catch(Exception e){
             e.printStackTrace();
            return  new ResultBody("10022","添加失败");
        }
    }

     //动态获取下拉框的值
    @RequestMapping("toAdd")
    public List<SysDict> toAdd( @RequestParam(value = "orderNo",required = false) String orderNo) {
        List<SysDict> typeList = systemService.querySysDictInfo(SysConstant.VACATION_TYPE);
       // model.addAttribute("typeList",typeList); org.springframework.ui.Model model,

//        if(StrUtil.isNotBlank(orderNo)) {//编辑
//            VacationOrder vacationOrder = vacationOrderService.queryVacation(Long.valueOf(orderNo));
//          //  model.addAttribute("vacationOrder",vacationOrder);
//
//        }
         return typeList;
    }

    /**
     * 提交请假申请
     * @return
     */
    @PostMapping("submitApply")
    @ResponseBody
    public ResultBody submitApply(@RequestParam("vacationId") String vacationId) {
        boolean res = vacationOrderService.submitApply(Long.valueOf(vacationId));
        if(res){
            return new ResultBody("10031","成功");
        }else {
            return new ResultBody("10032","提交申请失败");
        }
    }

    /**
     * 删除请假条
     * @param vacationId
     * @return
     */
    @PostMapping("delVacation")
    @ResponseBody
    public ResultBody delVacation(@RequestParam("vacationId") Long vacationId) {
        vacationOrderService.delVacation(vacationId);
         return new ResultBody("10041","成功");
    }


}
